<template>
  <div class="video-player" :class="{ 'fullscreen': isFullscreen }">
    <!-- 视频容器 -->
    <div class="video-container" @click="togglePlay" @dblclick="toggleFullscreen">
      <video
        ref="videoRef"
        :src="videoUrl"
        :poster="posterUrl"
        preload="metadata"
        class="video-element"
        @loadstart="handleLoadStart"
        @loadedmetadata="handleLoadedMetadata"
        @loadeddata="handleLoadedData"
        @canplay="handleCanPlay"
        @canplaythrough="handleCanPlayThrough"
        @play="handlePlay"
        @pause="handlePause"
        @ended="handleEnded"
        @timeupdate="handleTimeUpdate"
        @progress="handleProgress"
        @error="handleError"
        @waiting="handleWaiting"
        @playing="handlePlaying"
        @volumechange="handleVolumeChange"
      />

      <!-- 加载状态 -->
      <div v-if="loading" class="video-loading">
        <el-icon class="loading-icon" size="48"><Loading /></el-icon>
        <p>视频加载中...</p>
      </div>

      <!-- 错误状态 -->
      <div v-if="error" class="video-error">
        <el-icon class="error-icon" size="48"><Warning /></el-icon>
        <p>{{ error }}</p>
        <el-button @click="retry">重试</el-button>
      </div>

      <!-- 播放按钮覆盖层 -->
      <div v-if="showPlayButton" class="play-button-overlay" @click="togglePlay">
        <el-icon class="play-icon" size="64">
          <VideoPlay v-if="!isPlaying" />
          <VideoPause v-else />
        </el-icon>
      </div>

      <!-- 控制栏 -->
      <div 
        class="video-controls" 
        :class="{ 'visible': showControls }"
        @mouseenter="keepControlsVisible"
        @mouseleave="hideControlsDelayed"
      >
        <!-- 进度条 -->
        <div class="progress-container">
          <div class="progress-bar" @click="seekTo">
            <div class="progress-loaded" :style="{ width: loadedProgress + '%' }"></div>
            <div class="progress-played" :style="{ width: playedProgress + '%' }"></div>
            <div class="progress-thumb" :style="{ left: playedProgress + '%' }"></div>
          </div>
        </div>

        <!-- 控制按钮 -->
        <div class="controls-row">
          <!-- 左侧控制 -->
          <div class="controls-left">
            <el-button 
              text 
              :icon="isPlaying ? VideoPause : VideoPlay" 
              @click="togglePlay"
              title="播放/暂停"
            />
            <el-button 
              text 
              :icon="isMuted ? Mute : Mute" 
              @click="toggleMute"
              title="静音"
            />
            <div class="volume-control">
              <el-slider
                v-model="volume"
                :min="0"
                :max="100"
                @change="handleVolumeChange"
                style="width: 80px"
              />
            </div>
            <span class="time-display">
              {{ formatTime(currentTime) }} / {{ formatTime(duration) }}
            </span>
          </div>

          <!-- 右侧控制 -->
          <div class="controls-right">
            <el-button 
              text 
              :icon="FullScreen" 
              @click="toggleFullscreen"
              title="全屏"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import {
  VideoPlay,
  VideoPause,
  Mute,
  FullScreen,
  Loading,
  Warning
} from '@element-plus/icons-vue'

// 组件属性
interface Props {
  videoUrl: string
  posterUrl?: string
  autoplay?: boolean
  muted?: boolean
  controls?: boolean
  width?: string
  height?: string
}

const props = withDefaults(defineProps<Props>(), {
  videoUrl: '',
  posterUrl: '',
  autoplay: false,
  muted: false,
  controls: true,
  width: '100%',
  height: '400px'
})

// 组件事件
const emit = defineEmits<{
  play: []
  pause: []
  ended: []
  timeupdate: [currentTime: number]
  error: [error: string]
  loadstart: []
  canplay: []
}>()

// 响应式数据
const videoRef = ref<HTMLVideoElement>()
const loading = ref(true)
const error = ref('')
const isPlaying = ref(false)
const isMuted = ref(props.muted)
const volume = ref(100)
const currentTime = ref(0)
const duration = ref(0)
const loadedProgress = ref(0)
const isFullscreen = ref(false)
const showControls = ref(true)
const showPlayButton = ref(true)
const controlsTimer = ref<number>()

// 计算属性
const playedProgress = computed(() => {
  return duration.value > 0 ? (currentTime.value / duration.value) * 100 : 0
})

// 监听器
watch(() => props.videoUrl, (newUrl) => {
  if (newUrl) {
    loadVideo()
  }
})

watch(() => props.muted, (newMuted) => {
  isMuted.value = newMuted
  if (videoRef.value) {
    videoRef.value.muted = newMuted
  }
})

// 生命周期
onMounted(() => {
  if (props.videoUrl) {
    loadVideo()
  }
  setupEventListeners()
})

onUnmounted(() => {
  cleanup()
})

// 方法
const loadVideo = () => {
  loading.value = true
  error.value = ''
  
  if (videoRef.value) {
    videoRef.value.load()
  }
}

const setupEventListeners = () => {
  // 键盘事件
  document.addEventListener('keydown', handleKeydown)
  
  // 全屏事件
  document.addEventListener('fullscreenchange', handleFullscreenChange)
}

const cleanup = () => {
  document.removeEventListener('keydown', handleKeydown)
  document.removeEventListener('fullscreenchange', handleFullscreenChange)
  
  if (controlsTimer.value) {
    clearTimeout(controlsTimer.value)
  }
}

// 视频事件处理
const handleLoadStart = () => {
  loading.value = true
  emit('loadstart')
}

const handleLoadedMetadata = () => {
  if (videoRef.value) {
    duration.value = videoRef.value.duration
  }
}

const handleLoadedData = () => {
  loading.value = false
}

const handleCanPlay = () => {
  loading.value = false
  emit('canplay')
}

const handleCanPlayThrough = () => {
  loading.value = false
}

const handlePlay = () => {
  isPlaying.value = true
  showPlayButton.value = false
  emit('play')
}

const handlePause = () => {
  isPlaying.value = false
  showPlayButton.value = true
  emit('pause')
}

const handleEnded = () => {
  isPlaying.value = false
  showPlayButton.value = true
  currentTime.value = 0
  emit('ended')
}

const handleTimeUpdate = () => {
  if (videoRef.value) {
    currentTime.value = videoRef.value.currentTime
    emit('timeupdate', currentTime.value)
  }
}

const handleProgress = () => {
  if (videoRef.value && videoRef.value.buffered.length > 0) {
    const bufferedEnd = videoRef.value.buffered.end(videoRef.value.buffered.length - 1)
    loadedProgress.value = duration.value > 0 ? (bufferedEnd / duration.value) * 100 : 0
  }
}

const handleError = (event: Event) => {
  loading.value = false
  error.value = '视频加载失败'
  emit('error', error.value)
  console.error('视频播放错误:', event)
}

const handleWaiting = () => {
  loading.value = true
}

const handlePlaying = () => {
  loading.value = false
}

const handleVolumeChange = () => {
  if (videoRef.value) {
    volume.value = Math.round(videoRef.value.volume * 100)
    isMuted.value = videoRef.value.muted
  }
}

// 控制方法
const togglePlay = () => {
  if (!videoRef.value) return
  
  if (isPlaying.value) {
    videoRef.value.pause()
  } else {
    videoRef.value.play().catch(err => {
      console.error('播放失败:', err)
      error.value = '播放失败'
    })
  }
}

const toggleMute = () => {
  if (videoRef.value) {
    videoRef.value.muted = !videoRef.value.muted
    isMuted.value = videoRef.value.muted
  }
}

const toggleFullscreen = () => {
  if (!document.fullscreenElement) {
    videoRef.value?.requestFullscreen?.()
  } else {
    document.exitFullscreen?.()
  }
}

const seekTo = (event: MouseEvent) => {
  if (!videoRef.value || duration.value === 0) return
  
  const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()
  const percent = (event.clientX - rect.left) / rect.width
  const seekTime = percent * duration.value
  
  videoRef.value.currentTime = seekTime
}

const retry = () => {
  error.value = ''
  loadVideo()
}

// 控制栏显示/隐藏
const keepControlsVisible = () => {
  showControls.value = true
  if (controlsTimer.value) {
    clearTimeout(controlsTimer.value)
  }
}

const hideControlsDelayed = () => {
  if (controlsTimer.value) {
    clearTimeout(controlsTimer.value)
  }
  
  controlsTimer.value = setTimeout(() => {
    if (isPlaying.value) {
      showControls.value = false
    }
  }, 3000)
}

// 键盘事件
const handleKeydown = (event: KeyboardEvent) => {
  if (!videoRef.value) return
  
  switch (event.code) {
    case 'Space':
      event.preventDefault()
      togglePlay()
      break
    case 'ArrowLeft':
      event.preventDefault()
      videoRef.value.currentTime = Math.max(0, videoRef.value.currentTime - 10)
      break
    case 'ArrowRight':
      event.preventDefault()
      videoRef.value.currentTime = Math.min(duration.value, videoRef.value.currentTime + 10)
      break
    case 'ArrowUp':
      event.preventDefault()
      volume.value = Math.min(100, volume.value + 10)
      videoRef.value.volume = volume.value / 100
      break
    case 'ArrowDown':
      event.preventDefault()
      volume.value = Math.max(0, volume.value - 10)
      videoRef.value.volume = volume.value / 100
      break
    case 'KeyM':
      event.preventDefault()
      toggleMute()
      break
    case 'KeyF':
      event.preventDefault()
      toggleFullscreen()
      break
  }
}

// 全屏事件
const handleFullscreenChange = () => {
  isFullscreen.value = !!document.fullscreenElement
}

// 工具函数
const formatTime = (seconds: number): string => {
  if (isNaN(seconds)) return '00:00'
  
  const mins = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
}

// 暴露方法给父组件
defineExpose({
  play: () => videoRef.value?.play(),
  pause: () => videoRef.value?.pause(),
  seek: (time: number) => {
    if (videoRef.value) {
      videoRef.value.currentTime = time
    }
  },
  setVolume: (vol: number) => {
    volume.value = vol
    if (videoRef.value) {
      videoRef.value.volume = vol / 100
    }
  }
})
</script>

<style scoped lang="scss">
.video-player {
  position: relative;
  width: 100%;
  // background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
  border-radius: 5px;
  overflow: hidden;
  // box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  transition: all 0.3s ease;
  &.fullscreen {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 9999;
    border-radius: 0;
    box-shadow: none;
  }
}

.video-container {
  position: relative;
  width: 100%;
  height: 100%;
  cursor: pointer;
  background: radial-gradient(circle at center, #1a1a1a 0%, #000 100%);
}

.video-element {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: transparent;
  transition: filter 0.3s ease;

  &:hover {
    filter: brightness(1.05);
  }
}

.video-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #fff;
  z-index: 10;
  background: rgba(0, 0, 0, 0.7);
  padding: 24px 32px;
  border-radius: 16px;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);

  .loading-icon {
    animation: spin 1s linear infinite;
    margin-bottom: 16px;
    color: #409eff;
    filter: drop-shadow(0 0 8px rgba(64, 158, 255, 0.3));
  }

  p {
    margin: 0;
    font-size: 15px;
    font-weight: 500;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  }
}

.video-error {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #fff;
  z-index: 10;

  .error-icon {
    color: #f56c6c;
    margin-bottom: 12px;
  }

  p {
    margin: 0 0 16px 0;
    font-size: 14px;
  }
}

.play-button-overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 5;

  .play-icon {
    color: #fff;
    background: linear-gradient(135deg, rgba(64, 158, 255, 0.8) 0%, rgba(64, 158, 255, 0.6) 100%);
    border-radius: 50%;
    padding: 20px;
    transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    backdrop-filter: blur(10px);
    border: 2px solid rgba(255, 255, 255, 0.2);
    box-shadow: 0 8px 32px rgba(64, 158, 255, 0.3);

    &:hover {
      background: linear-gradient(135deg, rgba(64, 158, 255, 1) 0%, rgba(64, 158, 255, 0.8) 100%);
      transform: scale(1.15);
      box-shadow: 0 12px 48px rgba(64, 158, 255, 0.4);
      border-color: rgba(255, 255, 255, 0.3);
    }

    &:active {
      transform: scale(1.05);
    }
  }
}

.video-controls {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.9));
  backdrop-filter: blur(5px);
  padding: 12px 19px 12px;
  opacity: 0;
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 10;
  //border-top: 1px solid rgba(255, 255, 255, 0.1);

  &.visible {
    opacity: 1;
    transform: translateY(0);
  }

  &:not(.visible) {
    transform: translateY(10px);
  }
}

.progress-container {
  margin-bottom: 12px;
}

.progress-bar {
  position: relative;
  height: 5px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 3px;
  cursor: pointer;
  transition: all 0.3s ease;

  &:hover {
    height: 7px;
    background: rgba(255, 255, 255, 0.3);

    .progress-thumb {
      opacity: 1;
      transform: translate(-50%, -50%) scale(1.2);
    }
  }
}

.progress-loaded {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: rgba(255, 255, 255, 0.4);
  border-radius: 3px;
  transition: width 0.2s ease;
}

.progress-played {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: linear-gradient(90deg, #409eff 0%, #67c23a 100%);
  border-radius: 3px;
  transition: width 0.2s ease;
  box-shadow: 0 0 8px rgba(64, 158, 255, 0.3);
}

.progress-thumb {
  position: absolute;
  top: 50%;
  width: 14px;
  height: 14px;
  background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.4);
  border: 2px solid #fff;
}

.controls-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.controls-left {
  display: flex;
  align-items: center;
  gap: 12px;

  .el-button {
    color: rgba(255, 255, 255, 0.9);
    padding: 8px;
    border-radius: 8px;
    transition: all 0.3s ease;
    backdrop-filter: blur(5px);

    &:hover {
      color: #409eff;
      background: rgba(64, 158, 255, 0.1);
      transform: scale(1.05);
    }

    &:active {
      transform: scale(0.95);
    }
  }
}

.controls-right {
  display: flex;
  align-items: center;
  gap: 12px;

  .el-button {
    color: rgba(255, 255, 255, 0.9);
    padding: 8px;
    border-radius: 8px;
    transition: all 0.3s ease;
    backdrop-filter: blur(5px);

    &:hover {
      color: #409eff;
      background: rgba(64, 158, 255, 0.1);
      transform: scale(1.05);
    }

    &:active {
      transform: scale(0.95);
    }
  }
}

.volume-control {
  display: flex;
  align-items: center;

  :deep(.el-slider) {
    .el-slider__runway {
      background-color: rgba(255, 255, 255, 0.3);
    }

    .el-slider__bar {
      background-color: #409eff;
    }

    .el-slider__button {
      border-color: #409eff;
    }
  }
}

.time-display {
  color: rgba(255, 255, 255, 0.9);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  margin-left: 12px;
  padding: 4px 8px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 6px;
  backdrop-filter: blur(5px);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.7;
  }
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

// 响应式设计
@media (max-width: 768px) {
  .video-player {
    border-radius: 8px;
  }

  .video-controls {
    padding: 20px 16px 16px;
    backdrop-filter: blur(15px);
  }

  .controls-left {
    gap: 8px;
  }

  .controls-right {
    gap: 8px;
  }

  .volume-control {
    display: none;
  }

  .time-display {
    font-size: 12px;
    padding: 3px 6px;
    margin-left: 8px;
  }

  .play-button-overlay .play-icon {
    padding: 16px;
  }

  .progress-bar {
    height: 6px;

    &:hover {
      height: 8px;
    }
  }

  .progress-thumb {
    width: 16px;
    height: 16px;
  }
}

@media (max-width: 480px) {
  .video-controls {
    padding: 16px 12px 12px;
  }

  .controls-left,
  .controls-right {
    gap: 6px;
  }

  .time-display {
    font-size: 11px;
    padding: 2px 4px;
  }

  .play-button-overlay .play-icon {
    padding: 14px;
  }
}
</style>
